package com.bjut.vendormgrsys.service.impl;

import com.bjut.vendormgrsys.constant.Constant.NewsStatus;
import com.bjut.vendormgrsys.model.domain.SystemVideoPO;
import com.bjut.vendormgrsys.model.repository.SystemVideoRepository;
import com.bjut.vendormgrsys.service.SystemVideoService;
import com.bjut.vendormgrsys.util.DateUtils;
import com.bjut.vendormgrsys.web.dto.Status;
import com.bjut.vendormgrsys.web.dto.systemVideo.SystemVideoInfo;
import com.bjut.vendormgrsys.web.dto.systemVideo.SystemVideoSearch;
import com.bjut.vendormgrsys.web.dto.user.Body;
import lombok.extern.java.Log;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.Predicate;
import java.util.*;
import java.util.stream.Collectors;

@Log
@Service
public class SystemVideoServiceImpl implements SystemVideoService {
    @PersistenceContext
    private EntityManager entityManager;

    SystemVideoRepository systemVideoRepository;
    FileUtilService fileUtilService;

    @Autowired
    public SystemVideoServiceImpl(SystemVideoRepository systemVideoRepository, FileUtilService fileUtilService){
        this.systemVideoRepository = systemVideoRepository;
        this.fileUtilService = fileUtilService;
    }

    @Override
    @Transactional
    public void saveNews(SystemVideoInfo systemVideoInfo) {
        String id = systemVideoInfo.getId();
        SystemVideoPO systemVideoPO = null;
        boolean isPersist = true;
        List<String> ignorePropList = new ArrayList<>();
        if (StringUtils.hasLength(id)) {
            Optional<SystemVideoPO> byId = systemVideoRepository.findById(id);
            if (byId.isPresent()) {
                ignorePropList.add("creatorId");
                ignorePropList.add("status");
                ignorePropList.add("dateCreated");

                systemVideoPO = byId.get();
                isPersist = false;
            }
        }
        if (systemVideoPO == null) {
            systemVideoPO = new SystemVideoPO();
        }

        if(systemVideoInfo.getFile() != null){

            if(!isPersist){
                String oldPath = systemVideoPO.getFilePath();
                fileUtilService.delFile(oldPath);
            }

            // 保存新文件
            String newPath = fileUtilService.uploadFile(systemVideoInfo.getFile(), "systemVideo");
            String fileName = systemVideoInfo.getFile().getOriginalFilename();
            systemVideoInfo.setFileName(fileName);
            systemVideoInfo.setFilePath(newPath);
        }

        ignorePropList.add("lastUpdated");
        String[] ignoreProps = new String[ignorePropList.size()];
        ignorePropList.toArray(ignoreProps);
        BeanUtils.copyProperties(systemVideoInfo, systemVideoPO, ignoreProps);
        systemVideoPO.setLastUpdated(DateUtils.now());
        if (!isPersist) {
            entityManager.merge(systemVideoPO);
        } else {
            entityManager.persist(systemVideoPO);
        }
        entityManager.flush();
    }

    @Override
    public long findAll(SystemVideoSearch body, List<SystemVideoInfo> list) {
        int page = 1;
        int size = 10;
        Integer pageNum = body.getPageNum();
        if (pageNum != null) {
            page = pageNum;
        }
        page -= 1;
        Integer pageSize = body.getPageSize();
        if (pageSize != null) {
            size = pageSize;
        }
        // 根据动态条件从数据库分页查询用户信息
        Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "lastUpdated");

        Specification<SystemVideoPO> specification = (Specification<SystemVideoPO>) (root, query, builder) -> {
            List<Predicate> predicates = new ArrayList<>();
            String name = body.getName();
            if (StringUtils.hasLength(name)) {
                predicates.add(builder.like(root.get("name").as(String.class), "%" + name + "%"));
            }

            String creatorId = body.getCreatorId();
            if (StringUtils.hasLength(creatorId)) {
                predicates.add(builder.equal(root.get("creatorId").as(String.class), creatorId));
            }

            String status = body.getStatus();
            if (StringUtils.hasLength(status)) {
                predicates.add(builder.equal(root.get("status").as(String.class), status));
            }

            return builder.and(predicates.toArray(new Predicate[0]));
        };
        Page<SystemVideoPO> pageAll = systemVideoRepository.findAll(specification, pageable);
        List<SystemVideoPO> all = pageAll.getContent();
        for (SystemVideoPO systemVideoPO : all) {
            SystemVideoInfo systemVideoInfo = new SystemVideoInfo();
            BeanUtils.copyProperties(systemVideoPO, systemVideoInfo);
            list.add(systemVideoInfo);
        }
        return pageAll.getTotalElements();
    }

    @Override
    @Transactional
    public void changeStatus(List<Body> bodies) {
        for (Body body : bodies) {
            String id = body.getId();
            if (!StringUtils.hasLength(id)) {
                throw new RuntimeException("ID不能为空");
            }
            String status = body.getStatus();
            if (!StringUtils.hasLength(status)) {
                throw new RuntimeException("状态不能为空");
            }
            // 校验用户状态有效
            NewsStatus.getNameByKey(status);
            Optional<SystemVideoPO> byId = systemVideoRepository.findById(id);
            if (!byId.isPresent()) {
                throw new RuntimeException("数据不存在！");
            }
            SystemVideoPO systemVideoPO = byId.get();

            systemVideoPO.setStatus(status);
            systemVideoPO.setLastUpdated(DateUtils.now());

            if(status.equals(NewsStatus.PUBLISHED.getKey())){
                String publishedTime = DateUtils.formatDate((new Date()).getTime(), DateUtils.Pattern.PATTERN_DEFAULT);
                systemVideoPO.setPublishedTime(publishedTime);
            }
            entityManager.merge(systemVideoPO);
        }
        entityManager.flush();
    }

    @Override
    public SystemVideoInfo findById(String id) {
        Optional<SystemVideoPO> byId = systemVideoRepository.findById(id);
        if (!byId.isPresent()) {
            throw new RuntimeException("数据不存在！");
        }
        SystemVideoPO systemVideoPO = byId.get();

        SystemVideoInfo systemVideoInfo = new SystemVideoInfo();
        BeanUtils.copyProperties(systemVideoPO, systemVideoInfo);

        return systemVideoInfo;
    }

    @Override
    public List<Status> findAllStatus() {
        List<Status> statusList = new LinkedList<>();
        List<SystemVideoPO> all = systemVideoRepository.findAll();

        statusList.add(new Status().key("ALL").name("全部").value(all.size()));

        Map<String, Long> collect = all.stream().collect(Collectors.groupingBy(SystemVideoPO::getStatus, Collectors.counting()));
        NewsStatus[] statusAll = NewsStatus.values();
        for (NewsStatus newsStatus:statusAll){
            Status status = adapterStatus(collect, newsStatus.getKey(), newsStatus.getName());
            statusList.add(status);
        }

        return statusList;
    }

    private Status adapterStatus(Map<String, Long> collect, String key, String name){
        int value = 0;
        if(collect.containsKey(key)){
            value = collect.get(key).intValue();
        }
        Status status = new Status().key(key).name(name).value(value);
        return status;
    }
}
